home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gamers Delight 2
/
Gamers Delight 2.iso
/
Aminet
/
game
/
gag
/
snow.lha
/
Snow
/
snow.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-15
|
13KB
|
672 lines
#include <exec/memory.h>
#include <exec/execbase.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <dos/stdio.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <dos/rdargs.h>
#include <clib/asl_protos.h>
#include <clib/diskfont_protos.h>
#include <clib/commodities_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/macros.h>
#include <clib/alib_protos.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#ifdef __SASC /* some stuff for SAS-C */
#include <pragmas/commodities_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/gadtools_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#define VOID_INTERRUPT void __interrupt __saveds
#define REGARGS(rv) rv __regargs
#define CHIP(dt) dt __chip
//void NewList(struct List *);
UBYTE *VersionString = "$VER: Snow 0.1(compiled with SAS/C)";
void chkabort(void)
{}
#else /* DICE */
CxObj *HotKey(UBYTE *,struct MsgPort *,long);
UBYTE *VersionString = "$VER: Snow 0.1(compiled with DICE)";
void main(LONG,UBYTE **);
void wbmain(struct WBStartup *WBS)
{
if (WBS->sm_NumArgs) (void)CurrentDir(WBS->sm_ArgList->wa_Lock);
main(0L,(UBYTE **)WBS);
}
#endif
#define MASK(n) (1L<<(n))
#define WHITEPEN 1
#define BLACKPEN 0
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern struct Library *GadToolsBase;
extern struct Library *DOSBase;
WORD LeftEdge=12,TopEdge=12;
struct Window *TinyWindow;
struct TextAttr TinyAttr={"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT};
struct Screen *PubScreen;
struct RastPort *RP;
LONG Depth;
UWORD backdrop=FALSE;
/*
The following functions are taken from Matthias Schelers' resource tracker
library for SAS/C. Thanks to Matthias.
*/
struct ToolNode
{
struct ToolNode *Next;
void *Tool;
void (*RemProc)(void *,LONG); /* requires stack arguments !!! */
LONG Size;
} *ToolList;
REGARGS(void) RemTool(void *Tool)
{
struct ToolNode **Ptr,*ToolNode;
Ptr=&ToolList;
while (ToolNode=*Ptr)
if (ToolNode->Tool==Tool)
{
*Ptr=ToolNode->Next;
ToolNode->RemProc(ToolNode->Tool,ToolNode->Size);
FreeVec ((APTR)ToolNode);
return; /* This one was missing in ASwarm II V1.0-V1.1 and in
ASwarm III :-) */
}
else Ptr=&ToolNode->Next;
}
void RemoveAll(void)
{
while (ToolList) RemTool (ToolList->Tool);
}
REGARGS(void) AddTool(void *NewTool,void *ProcPtr,LONG NewSize)
{
struct ToolNode *Ptr;
void (*NewRemProc)(void *,LONG);
static BOOL First=TRUE;
NewRemProc=(void (*)(void *,LONG))ProcPtr;
if (NewTool==NULL) exit (10);
if (First)
{
First=FALSE;
if (atexit(RemoveAll))
{
NewRemProc (NewTool,NewSize);
exit (20);
}
}
if ((Ptr=AllocVec(sizeof(struct ToolNode),0L))==NULL)
{
NewRemProc (NewTool,NewSize);
exit (20);
}
Ptr->Next=ToolList;
Ptr->Tool=NewTool;
Ptr->RemProc=NewRemProc;
Ptr->Size=NewSize;
ToolList=Ptr;
}
void CloseTinyWindow(void)
{
if (TinyWindow)
{
CloseWindow (TinyWindow);
TinyWindow=NULL;
}
}
void OpenTinyWindow(void)
{
ULONG Flags;
ULONG w,h;
Flags=WFLG_DRAGBAR| WFLG_DEPTHGADGET| WFLG_CLOSEGADGET|WFLG_RMBTRAP|
WFLG_SMART_REFRESH| WFLG_SIZEGADGET| WFLG_SIZEBBOTTOM;
if (TinyWindow==NULL)
{
if ((PubScreen=LockPubScreen(NULL))==NULL) return;
Depth=PubScreen->BitMap.Depth;
if(backdrop)
{
Flags=Flags|WFLG_BACKDROP|WFLG_BORDERLESS;
h=PubScreen->Height;
w=PubScreen->Width;
}
else
{
w=300;
h=200;
}
if ((TinyWindow=OpenWindowTags(NULL,
WA_Left,LeftEdge,
WA_Top,TopEdge,
WA_IDCMP,IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
IDCMP_NEWSIZE|IDCMP_VANILLAKEY|LISTVIEWIDCMP,
WA_Flags,Flags,
WA_AutoAdjust,TRUE,
WA_Title,(ULONG)"Snow - happy X-Mas!",
WA_PubScreen,PubScreen,
WA_InnerWidth,w,
WA_InnerHeight,h,
WA_MinWidth,50,
WA_MaxWidth,PubScreen->Width,
WA_MinHeight,50,
WA_MaxHeight,PubScreen->Height,
WA_GimmeZeroZero, TRUE,
TAG_DONE))==NULL)
{
CloseTinyWindow();
return;
}
GT_RefreshWindow (TinyWindow,NULL);
}
UnlockPubScreen(NULL,PubScreen);
ScreenToFront (TinyWindow->WScreen);
if(!backdrop)WindowToFront (TinyWindow);
ActivateWindow (TinyWindow);
RP=TinyWindow->RPort;
}
LONG RDArgsLong(LONG Param,LONG Default,LONG Min,LONG Max)
{
LONG *Ptr;
if ((Ptr=(LONG *)Param)==NULL) return Default;
if ((*Ptr<Min)||(*Ptr>Max)) return Default;
else return *Ptr;
}
#define RAND(m) (Random(m)-(m)/2)
#define MAXRAND 32768.0
/* Ill's strange and genius Random Function :-) */
int Random(int Max)
{
static ULONG Num=0L; /* So the last random-number is still stored ! */
ULONG Sec,Mic;
CurrentTime((LONG *)&Sec,(LONG *)&Mic);
Num*=Sec+1/Sec;
Num+=Mic;
while (Num>MAXRAND) Num=Num>>1;
return (int)(Num % Max);
}
/* Template for ReadArg */
static char *Template = "SNOWFLAKES/N/K,BACKDROP/S";
#include "snowmap.h"
typedef unsigned long Pixel;
#define SCAMPER_EVENT (LASTEvent + 1)
unsigned int display_width, display_height;
int center_x, center_y;
int done = 0;
int eventBlock = 0;
int errorVal = 0;
int flake;
Snow *snowflakes;
int maxSnowflakes = 100;
int curSnowflakes = 0;
#define SNOWCOLOR 1
#define SANTACOLOR 2
#define BAUMCOLOR 3
#define HATCOLOR 4
Santa Claus;
void Usage(void);
void InitSnowflake(int);
void UpdateSnowflake(int);
void DrawSnowflake(int);
void EraseSnowflake(int);
void DrawTannenbaum(int,int);
void InitSanta(void);
void DrawSanta(void);
void EraseSanta(void);
void UpdateSanta(void);
void usleep(unsigned int);
void main_initsanta(int, char**);
void drawsnowstorm(void);
int RandInt(int);
int SnowInRect(Snow*, int, int, int, int, unsigned int, unsigned int);
void main_initsanta(ac, av)
int ac;
char *av[];
{
int i;
display_width = TinyWindow->Width;
display_height = TinyWindow->Height;
center_x = display_width / 2;
center_y = display_height / 2;
/*
P I X M A P S
*/
/* Create the snowflake pixmaps */
/* Allocate structures containing the coordinates and things */
AddTool(snowflakes=(Snow *)AllocVec((sizeof(Snow)) * MAXSNOWFLAKES,MEMF_CLEAR),FreeVec,0L);
SetAPen(RP,1);
SetRast(RP,3);
SetBPen(RP,3);
SetDrMd(RP,JAM2);
/* Initialize all snowflakes */
for (i=0; i<maxSnowflakes; i++) InitSnowflake(i);
InitSanta();
for (i=0; i<maxSnowflakes; i++) DrawSnowflake(i);
}
#define USEPRT(msg) fprintf(stderr, msg)
void drawsnowstorm()
{
int i;
for (i=0; i<maxSnowflakes; i++) UpdateSnowflake(i);
/* Draw dear Andrew */
DrawTannenbaum(display_width-150, display_height-500);
DrawTannenbaum(display_width-100, display_height-200);
DrawTannenbaum(100, display_height-200);
DrawTannenbaum(50, display_height-150);
DrawTannenbaum(center_x, display_height-100);
DrawTannenbaum(200,400);
/* Dear Santa */
UpdateSanta();
}
/*
Generate random integer between 0 and maxVal-1.
*/
int
RandInt(maxVal)
int maxVal;
{
return rand() % maxVal;
}
/*
Check for snow completely in specified rectangle.
*/
int
SnowInRect(snow, rx, ry, x, y, width, height)
Snow *snow;
int rx;
int ry;
int x;
int y;
unsigned int width;
unsigned int height;
{
if (rx < x) return 0;
if ((rx + snowPix[snow->whatFlake].Width) > (x + width)) return 0;
if (ry < y) return 0;
if ((ry + snowPix[snow->whatFlake].Height) > (y + height)) return 0;
return 1;
}
/*
Give birth to a snowflake.
*/
void
InitSnowflake(rx)
int rx;
{
Snow *r;
r = &snowflakes[rx];
if (curSnowflakes < maxSnowflakes) {
r->whatFlake = Random(SNOWFLAKEMAXTYPE+1);
r->intX = Random(display_width - snowPix[r->whatFlake].Width);
r->intY = Random(display_height/10);
r->yStep = Random(MAXYSTEP+1)+1;
r->xStep = Random(r->yStep/4+1);
if (Random(1000) > 500) r->xStep = -r->xStep;
r->active = 1;
}
}
/*
Move a snowflake by erasing and redraw
*/
void
UpdateSnowflake(rx)
int rx;
{
Snow *snow;
/* move an active snowflake */
snow = &snowflakes[rx];
if (!snow->active) {
InitSnowflake(rx); /* For next time */
}
else {
/* This is an active snowflake */
EraseSnowflake(rx);
snow->intX = snow->intX + snow->xStep;
snow->intY = snow->intY + snow->yStep;
/* If flake disappears offscreen it becomes inactive */
snow->active = SnowInRect(snow, snow->intX, snow->intY,
0, 0, display_width, display_height);
/* Adjust horizontal speed to mimic whirling */
snow->xStep = snow->xStep + Random(WHIRLFACTOR+1);
if (Random(1000) > 500) snow->xStep = -snow->xStep;
if (snow->xStep > MAXXSTEP) snow->xStep = MAXXSTEP;
if (snow->xStep < -MAXXSTEP) snow->xStep = -MAXXSTEP;
/* Draw if still active */
if (snow->active) DrawSnowflake(rx);
}
}
/*
Draw a snowflake.
*/
void
DrawSnowflake(rx)
int rx;
{
Snow *snow;
snow = &snowflakes[rx];
DrawImage(RP,&snowPix[snow->whatFlake],snow->intX, snow->intY);
}
/*
Erase a snowflake.
*/
void
EraseSnowflake(rx)
int rx;
{
Snow *snow;
snow = &snowflakes[rx];
SetAPen(RP,3);
SetBPen(RP,1);
if (snow->intX >= 0) RectFill(RP,snow->intX,
snow->intY,
snow->intX+snowPix[snow->whatFlake].Width,
snow->intY+snowPix[snow->whatFlake].Height);
}
/*
Draw a tree
*/
void
DrawTannenbaum(x,y)
int x,y;
{
DrawImage(RP,&tannenbaumPix[0],x,y);
}
/*
Give birth to a Santa. (What a conception)
*/
void
InitSanta()
{
Claus.x = 0;
Claus.y = Random(display_height / 3);
Claus.xStep = 1;
Claus.yStep = 1;
Claus.whatSanta = 0;
}
/*
Update Santa (How can you update the oldest icon in the world? Oh well.
*/
void
UpdateSanta()
{
EraseSanta();
/* Move forward */
Claus.x = Claus.x + Claus.xStep;
/* Move down */
if (Random(10) > 3) Claus.y = Claus.y + Claus.yStep;
if (Claus.y < 0) Claus.y = 0;
if (Random(100) > 80) Claus.yStep = -Claus.yStep;
if (Claus.x >= display_width) InitSanta();
/* Next sleigh */
Claus.whatSanta++;
if (Claus.whatSanta > 2) Claus.whatSanta = 0;
DrawSanta();
}
/*
Draw Santa
*/
void
DrawSanta()
{
DrawImage(RP,&sleighPix[Claus.whatSanta],Claus.x,Claus.y);
/* The Man in the Red Suit himself */
DrawImage(RP,&santaPix[0],Claus.x,Claus.y);
SetAPen(RP,HATCOLOR);
WritePixel(RP,Claus.x+5,Claus.y+1);
}
/*
Erase Santa
*/
void
EraseSanta()
{
if (Claus.x >= 0) {
SetAPen(RP,3);
RectFill(RP,Claus.x,Claus.y,Claus.x+sleighPix[Claus.whatSanta].Width,
Claus.y+sleighPix[Claus.whatSanta].Height);
}
}
#define MASK(n) (1L<<(n))
void main(LONG argc,UBYTE **argv)
{
struct IntuiMessage *IntMsg;
struct RDArgs *RDArgs;
LONG Array[2];
/* open our Libraries */
AddTool (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",
37L),CloseLibrary,0L);
AddTool (GadToolsBase=OpenLibrary("gadtools.library",37L),CloseLibrary,0L);
AddTool (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L),
CloseLibrary,0L);
/*
Process command line options.
*/
(void)memset(Array,'\0',sizeof(Array));
if (RDArgs=ReadArgs(Template,Array,NULL))
{
if(Array[0]) maxSnowflakes=RDArgsLong(Array[1],100,1,200);
if(Array[1]) backdrop=Array[1];
}
else
{
PrintFault(IoErr(),"Snow");
exit (10);
}
if (RDArgs) FreeArgs(RDArgs);
AddTool ((void *)-1L,CloseTinyWindow,0L);
OpenTinyWindow();
main_initsanta(argc, argv);
/* start the Loop */
FOREVER
{
/* process Window Events */
while((TinyWindow!=NULL)&&(IntMsg=GT_GetIMsg(TinyWindow->UserPort)))
switch (IntMsg->Class)
{
UWORD Code;
case IDCMP_CLOSEWINDOW:
GT_ReplyIMsg (IntMsg);
CloseTinyWindow();
exit(0);
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh (TinyWindow);
GT_EndRefresh (TinyWindow,TRUE);
break;
case IDCMP_VANILLAKEY:
Code=IntMsg->Code;
GT_ReplyIMsg (IntMsg);
switch ((char)Code)
{
case 27: /* ESC */
CloseTinyWindow();
exit(0);
break;
}
break;
case IDCMP_NEWSIZE:
GT_ReplyIMsg (IntMsg);
main_initsanta(argc, argv);
break;
default:
GT_ReplyIMsg (IntMsg);
}
/* Busy Loop draw *grin :-)* */
drawsnowstorm();
if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
exit(0);
}
}
}